package com.junqi.live.room.domain.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.junqi.common.constant.MQConstant;
import com.junqi.common.entity.AjaxResult;
import com.junqi.common.entity.Message;
import com.junqi.common.entity.RedisKeyManager;
import com.junqi.common.entity.RoomLiveMq;
import com.junqi.live.room.common.annotation.RedissonLock;
import com.junqi.live.room.common.utils.LoginUtil;
import com.junqi.live.room.common.utils.RedisUtil;
import com.junqi.live.room.domain.bo.ChatMessageBo;
import com.junqi.live.room.domain.convert.LiveRoomBoConvert;
import com.junqi.live.room.domain.bo.LiveRoomBo;
import com.junqi.live.room.domain.service.LiveRoomDomainService;
import com.junqi.live.room.domain.service.SensitiveWordFilterService;
import com.junqi.live.room.infra.basic.entity.LiveRoom;
import com.junqi.live.room.infra.basic.entity.LiveRoomCollect;
import com.junqi.live.room.infra.basic.entity.LiveType;
import com.junqi.live.room.infra.basic.entity.SysUserRpc;
import com.junqi.live.room.infra.basic.rpc.UserRpc;
import com.junqi.live.room.infra.basic.service.LiveRoomCollectService;
import com.junqi.live.room.infra.basic.service.LiveRoomService;
import com.junqi.live.room.infra.basic.service.LiveTypeService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class LiveRoomDomainServiceImpl implements LiveRoomDomainService {

    @Resource
    LiveRoomService liveRoomService;
    @Resource
    RocketMQTemplate rocketMQTemplate;
    @Resource
    SensitiveWordFilterService wordFilterService;
    @Resource
    UserRpc userRpc;
    @Resource
    LiveTypeService liveTypeService;
    @Resource
    LiveRoomCollectService liveRoomCollectService;

    @Value(value = "${jq.file_prefix_url}")
    private String filePrefixUrl="";


    @Override
    public List<LiveRoomBo> listByTypeId(String typeId) {
        List<LiveRoom> liveRooms = liveRoomService.list(new QueryWrapper<LiveRoom>().eq("state",true)
                .eq(StrUtil.isNotBlank(typeId),"type_id",typeId));
        List<LiveRoomBo> roomBoList = liveRooms.stream().map(m -> LiveRoomBoConvert.INSTANCE.convertEntityToBO(m)).collect(Collectors.toList());
        for (LiveRoomBo liveRoomBo : roomBoList) {
            if(StrUtil.isNotBlank(liveRoomBo.getTypeId())){
                LiveType liveType = liveTypeService.getById(liveRoomBo.getTypeId());
                liveRoomBo.setTypeName(liveType.getName());
            }
            SysUserRpc sysUser = userRpc.getUserInfoByUserId(liveRoomBo.getUserId());
            liveRoomBo.setUserName(sysUser!=null?sysUser.getUserName():"");
        }
        return roomBoList;
    }

    @Override
    public LiveRoomBo getInfo(String id) {
        String loginId = LoginUtil.getLoginId();
        LiveRoom liveRoom = liveRoomService.getById(id);
        LiveRoomBo liveRoomBo = LiveRoomBoConvert.INSTANCE.convertEntityToBO(liveRoom);
        LiveType liveType = liveTypeService.getById(liveRoomBo.getTypeId());
        liveRoomBo.setTypeName(liveType.getName());
        if(StrUtil.isNotBlank(loginId)){
            int count = liveRoomCollectService.count(new QueryWrapper<LiveRoomCollect>().eq("user_id", loginId).eq("room_id", id));
            liveRoomBo.setCollect(count>0);
        }else{
            liveRoomBo.setCollect(false);
        }
        SysUserRpc sysUser = userRpc.getUserInfoByUserId(liveRoom.getUserId());
        liveRoomBo.setUserName(sysUser!=null?sysUser.getUserName():"");
        return liveRoomBo;
    }

    @Override
    public LiveRoomBo openPlay(LiveRoomBo liveRoomBo) {
        String loginId = LoginUtil.getLoginId();
        SysUserRpc sysUser = userRpc.getUserInfoByUserId(loginId);
        if(!"2".equals(sysUser.getRoleId())){
            AjaxResult.errorRun("你不是主播，不能开播！");
        }
        LiveRoom liveRoom = liveRoomService.getOne(new QueryWrapper<LiveRoom>().eq("user_id", sysUser.getId()).last("limit 1"));
        if(liveRoom==null){
            liveRoom=new LiveRoom();
            liveRoom.setAddUser(loginId);
            liveRoom.setAddTime(new Date());
            liveRoom.setState(false);
            liveRoom.setUserId(sysUser.getId());
            liveRoomService.save(liveRoom);
        }
        if(liveRoom.getState()){
            AjaxResult.errorRun("请勿重复开播！");
        }
        liveRoom.setCoverUrl(filePrefixUrl+"hls/"+liveRoom.getId()+"_image.jpg");
        liveRoom.setTitle(liveRoomBo.getTitle());
        liveRoom.setTypeId(liveRoomBo.getTypeId());
        liveRoom.setState(true);
        liveRoom.setUpdUser(loginId);
        liveRoom.setUpdTime(new Date());
        //生成随机rtmp直播码
        String rtmpCode = MD5.create().digestHex(liveRoom.getId()+RandomUtil.randomNumbers(6));
        liveRoom.setRtmpCode("?roomId="+liveRoom.getId()+"&rtmpCode="+rtmpCode);
        liveRoom.setRtmpUrl("rtmp://127.0.0.1:1935/live");
        liveRoomService.updateById(liveRoom);

        //推送mq开播消息
        RoomLiveMq roomLiveMq=new RoomLiveMq();
        roomLiveMq.setRoomId(liveRoom.getId());
        roomLiveMq.setRtmpCode(liveRoom.getRtmpCode());
        roomLiveMq.setRtmpUrl(liveRoom.getRtmpUrl());
        rocketMQTemplate.convertAndSend(MQConstant.ROOM_OPEN_PLAY_TOPIC,roomLiveMq);
        return LiveRoomBoConvert.INSTANCE.convertEntityToBO(liveRoom);
    }

    @Override
    public void closePlay() {
        String loginId = LoginUtil.getLoginId();
        LiveRoom liveRoom = liveRoomService.getOne(new QueryWrapper<LiveRoom>().eq("user_id", loginId).last("limit 1"));
        if(liveRoom==null){
            AjaxResult.errorRun("查询不到直播信息！");
        }
        liveRoom.setTitle("");
        liveRoom.setTypeId("");
        liveRoom.setState(false);
        liveRoom.setUpdUser(loginId);
        liveRoom.setUpdTime(new Date());
        liveRoom.setRtmpCode("");
        liveRoom.setRtmpUrl("");
        liveRoomService.updateById(liveRoom);

        //推送mq关播消息
        RoomLiveMq roomLiveMq=new RoomLiveMq();
        roomLiveMq.setRoomId(liveRoom.getId());
        rocketMQTemplate.convertAndSend(MQConstant.ROOM_CLOSE_PLAY_TOPIC,roomLiveMq);
    }

    @Override
    public LiveRoomBo getRoomUserInfo() {
        String loginId = LoginUtil.getLoginId();
        SysUserRpc sysUser = userRpc.getUserInfoByUserId(loginId);
        if(!"2".equals(sysUser.getRoleId())){
           return null;
        }
        LiveRoom liveRoom = liveRoomService.getOne(new QueryWrapper<LiveRoom>().eq("user_id", sysUser.getId()).last("limit 1"));
        return LiveRoomBoConvert.INSTANCE.convertEntityToBO(liveRoom);
    }

    @Override
    public List<LiveRoomBo> getRoomCollectList() {
        String loginId = LoginUtil.getLoginId();
        List<LiveRoomCollect> roomCollectList = liveRoomCollectService.list(new QueryWrapper<LiveRoomCollect>().eq("user_id", loginId).orderByAsc("add_time"));
        if(CollUtil.isEmpty(roomCollectList)){
            return null;
        }
        List<LiveRoomBo> roomBoList=new ArrayList<>();
        for (LiveRoomCollect collect : roomCollectList) {
            LiveRoom liveRoom = liveRoomService.getById(collect.getRoomId());
            LiveRoomBo liveRoomBo = LiveRoomBoConvert.INSTANCE.convertEntityToBO(liveRoom);
            if(StrUtil.isNotBlank(liveRoomBo.getTypeId())){
                LiveType liveType = liveTypeService.getById(liveRoomBo.getTypeId());
                liveRoomBo.setTypeName(liveType.getName());
            }
            roomBoList.add(liveRoomBo);
        }
        return roomBoList;
    }

    @Override
    @RedissonLock
    public void updateCollect(String roomId, Boolean select) {
        String loginId = LoginUtil.getLoginId();
        int count = liveRoomCollectService.count(new QueryWrapper<LiveRoomCollect>().eq("user_id", loginId).eq("room_id", roomId));
        if(select){
            if(count>0){
                AjaxResult.errorRun("你已关注，请勿重复关注！");
            }
            LiveRoomCollect liveRoomCollect=new LiveRoomCollect();
            liveRoomCollect.setUserId(loginId);
            liveRoomCollect.setRoomId(roomId);
            liveRoomCollect.setAddTime(new Date());
            liveRoomCollectService.save(liveRoomCollect);
        }else{
            if(count==0){
                AjaxResult.errorRun("你还未关注，取消关注失败！");
            }
            liveRoomCollectService.remove(new QueryWrapper<LiveRoomCollect>().eq("user_id", loginId).eq("room_id", roomId));
        }
    }

    @Override
    public Message sendMsg(ChatMessageBo chatMessageBo) {
        String loginId = LoginUtil.getLoginId();
        SysUserRpc sysUser = userRpc.getUserInfoByUserId(loginId);
        Message message=new Message();
        message.setId(RedisUtil.generateId(RedisKeyManager.generateKey(RedisKeyManager.ROOM_MSG_ID,chatMessageBo.getRoomId())));
        message.setSendTime(System.currentTimeMillis());
        message.setUserName(sysUser.getUserName());
        message.setUserId(sysUser.getId());
        message.setRoomId(chatMessageBo.getRoomId());
        message.setType(chatMessageBo.getType());
        message.setBody(wordFilterService.filter(chatMessageBo.getBody()));
        rocketMQTemplate.convertAndSend(MQConstant.SEND_MSG_TOPIC,message);
        return message;
    }
}
